import type { DocumentFetchResult } from '../../../../../../lib/document_operator'
import type { ComponentStyleIdType } from '../../../../../../types/interfaces'
import type {
  UserAnalyticsActivity,
  UserAnalyticsCollectedData,
  UserAnalyticsCommentData,
  UserAnalyticsCommentScriptDistribution,
  UserAnalyticsConfig,
  UserAnalyticsCreationTimeDistribution,
  UserAnalyticsData,
  UserAnalyticsMultiPageOptions,
  UserAnalyticsPlatformConfig,
  UserAnalyticsScriptDailyInstallRanges,
  UserAnalyticsScriptData,
  UserAnalyticsScriptTotalInstallRanges,
  UserAnalyticsUserData,
} from './types'
import { BaseModule } from '../../../../../../lib/abstract'
import { PageManager } from '../../../../../../lib/abstract/page_manager'
import { DocumentOperator } from '../../../../../../lib/document_operator'
import { ICON_IDS } from '../../../../../../lib/icons/types/constants'
import { PageHandler } from '../../../../../../lib/page_handler'
import {
  GREASY_FORK_PAGINATION_CONFIG,
  GREASY_FORK_USER_SELECTORS,
  GreasyForkPageType,
} from '../../../../../../lib/page_handler/platform/greasyfork/types'
import { ToolKit } from '../../../../../../lib/utils/toolkit'
import {
  BodyAttrs,
  BUTTON_TEMPLATE_STYLES,
  ComponentStyleId,
  HOSTNAME,
  logger,
  PROJECT_PREFIX,
  SUPPORTED_PLATFORMS,
  TIME_UNITS,
  WEEKDAYS_CHINESE,
} from '../../../../../../types/constants'
import { SYMBOLS } from '../../../../../../types/interfaces'
import { ConfigManager } from '../../../../../config_manager'
import { ProgressManager } from './service/progress'
import { ProgressStage } from './service/progress/types'
import { UserAnalyticsUI } from './service/ui'
import {
  USER_ANALYTICS_MAX_COMMENT_PAGES,
  UserAnalyticsCommentRole,
} from './types'

interface Config {
  enabled?: boolean
}

/**
 * 测试链接：
 * 1）https://greasyfork.org/zh-CN/users/594536-i9l121-ihr8f
 * 2）https://greasyfork.org/zh-CN/users/1297357-emree-el
 * 3）https://greasyfork.org/zh-CN/users/18978-indarkness
 * 4）https://greasyfork.org/zh-CN/users/189391-ignore
 */
export class UserAnalytics extends BaseModule {
  // @Decorators.Identity
  readonly id: string = 'user_analytics'
  get name(): ComponentStyleIdType {
    return 'UserAnalytics'
  }

  // @Decorators.InheritedConfig
  readonly styleId: string = ComponentStyleId[this.name]
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  // @Decorators.PublicState
  isInitialized: boolean = false
  private static instance: UserAnalytics
  // @Decorators.CoreDependency
  private uiService: UserAnalyticsUI = UserAnalyticsUI.getInstance(this)
  private progressManager = ProgressManager.getInstance()
  // @Decorators.Dependency
  private pageManager: PageManager = PageManager.getInstance()
  private documentOperator: DocumentOperator = DocumentOperator.getInstance()
  // @Decorators.UIElement
  private readonly BUTTON_ID: string = 'user-analytics-trigger'
  private readonly PROCESSED_ATTR: string = BodyAttrs.PROCESSED_ELEMENT
  $buttonElement: JQuery<HTMLElement> | null = null

  // @Decorators.Config
  get currentConfig(): UserAnalyticsConfig | undefined {
    return this.getCurrentConfig()
  }

  // @Decorators.TemporaryState
  discussionUrl: string = ''
  // 状态管理
  private isAnalysisRunning: boolean = false
  isDashboardRendered: boolean = false
  userData: UserAnalyticsCollectedData | null = null
  analyticsData: UserAnalyticsData | null = null
  // 分页控制
  private readonly enablePagination: boolean = true
  actualCommentPages: number = 1 // 实际获取页数
  private readonly COMMENT_START_PROGRESS: number = 30
  private readonly COMMENT_COLLECTED_PROGRESS: number = 45
  // 分页阈值
  private readonly maxCommentPages: number = USER_ANALYTICS_MAX_COMMENT_PAGES // 最大获取页数
  pageMaxCommentPages: number = 0 // 页面最大获取评论页数
  private get customMaxCommentPages(): number { // 用户自定义的最大获取页数
    return Number(this.pageManager.getPageNum())
  }

  config: Config = {
    enabled: true,
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): UserAnalytics {
    if (!UserAnalytics.instance) {
      UserAnalytics.instance = new UserAnalytics()
    }
    return UserAnalytics.instance
  }

  reset(): void {
    this.userData = null
    this.analyticsData = null
    this.isDashboardRendered = false

    this.uiService.clickOutsideHandler?.destroy()
    this.progressManager.destroy()
    this.uiService.destroy()
  }

  handleCleanupReferences(): void {
    this.reset()
  }

  handleCleanupOthers(): void {
    this.$buttonElement = null
    this.unregisterStyle(this.styleId)

    if (!this.currentConfig)
      return

    const { selector } = this.currentConfig

    // 移除处理标识
    $(selector).removeAttr(this.PROCESSED_ATTR)
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.setupAnalytics()

    // 注册样式
    this.registerStyle(this.styleId, this.getStyles())
  }

  onToggleCallback(_id: string, checked: boolean, first: boolean): void {
    super.onToggleCallback(_id, checked, first)
  }

  /**
   * 获取当前页面的配置
   */
  getCurrentConfig(): UserAnalyticsConfig | undefined {
    const config: UserAnalyticsPlatformConfig = {
      [SUPPORTED_PLATFORMS.GREASY_FORK]: {
        [GreasyForkPageType.USER_PROFILE]: GREASY_FORK_USER_SELECTORS,
      },
    }

    const currentConfig = config[HOSTNAME]?.[PageHandler.getCurrentPageType()]

    if (!currentConfig) {
      logger.warn(`[${this.name}] 未找到当前页面类型的配置`)
    }

    return currentConfig
  }

  /**
   * 设置用户分析
   */
  private setupAnalytics(): void {
    if (!this.currentConfig)
      return

    this.renderControlButton()
  }

  /**
   * 渲染控制按钮
   */
  private renderControlButton(): void {
    const buttonContainer = $(this.currentConfig!.buttonInsertSelector)

    if (!buttonContainer.length) {
      logger.warn(`[${this.name}] 未找到按钮容器，无法渲染控制按钮`)
      return
    }

    if (buttonContainer.find(`#${this.BUTTON_ID}`).length > 0)
      return

    const $button = $(`<button id="${this.BUTTON_ID}">${SYMBOLS.UI.CHART} 用户分析</button>`)
    this.$buttonElement = $button
    buttonContainer.prepend($button)

    $button.on('click', this.handleButtonClick.bind(this))
    this.tracker.creation($button)
    ToolKit.browser.platform.markProjectElement($button)

    logger.debug(`[${this.name}] 控制按钮已渲染`)
  }

  /**
   * 处理按钮点击事件
   */
  private async handleButtonClick(): Promise<void> {
    if (this.isAnalysisRunning) {
      // 如果正在运行，点击按钮可以取消
      if (this.progressManager)
        this.progressManager.cancel('用户点击取消')

      logger.debug(`[${this.name}] 分析正在进行中，跳过重复执行`)
      return
    }

    this.toggleButtonLoadingStatus(true)

    if (this.isDashboardRendered) {
      this.uiService.toggleDashboard()
      this.toggleButtonLoadingStatus(false)
      return
    }

    await this.executeAnalysis()
  }

  /**
   * 切换按钮加载状态
   */
  toggleButtonLoadingStatus(loading: boolean): void {
    this.$buttonElement?.toggleClass('loading', loading)
  }

  /**
   * 执行分析
   */
  private async executeAnalysis(): Promise<void> {
    this.isAnalysisRunning = true
    this.progressManager.start(() => this.handleAnalysisCancellation())

    try {
      logger.important(`[${this.name}] 开始分析用户`)

      // 检查是否已取消
      if (this.progressManager.isCancelled())
        return

      // 收集数据
      this.progressManager.updateToStep(ProgressStage.COLLECTING, '正在收集用户数据...', '准备数据收集环境')
      await this.collectAllData()

      // 检查是否已取消
      if (this.progressManager.isCancelled())
        return

      // 分析数据
      this.progressManager.updateToStep(ProgressStage.ANALYZING, '正在分析数据...', '处理收集到的信息')
      this.analyzeData()

      // 检查是否已取消
      if (this.progressManager.isCancelled())
        return

      // 渲染看板
      this.progressManager.updateToStep(ProgressStage.RENDERING, '正在生成可视化报告...', '创建图表和统计信息')
      this.uiService.renderDashboard()

      this.isDashboardRendered = true
      this.progressManager.complete('分析完成！', '可以查看详细报告了')
    }
    catch (error: any) {
      // 如果是取消操作，不记录为错误
      if (this.progressManager.isCancelled()) {
        logger.info(`[${this.name}] 分析已被用户取消`)
        return
      }

      logger.error(`[${this.name}] 分析执行失败`, error)
      this.progressManager.error(error, '分析过程出现错误，详情见控制台日志')
    }
    finally {
      this.isAnalysisRunning = false
      this.toggleButtonLoadingStatus(false)
    }
  }

  /**
   * 处理分析取消
   */
  private handleAnalysisCancellation(): void {
    logger.info(`[${this.name}] 用户取消了分析操作`)

    // 停止所有进行中的操作
    this.isAnalysisRunning = false
    this.toggleButtonLoadingStatus(false)

    // 清理资源
    this.cleanupAnalysis()
  }

  /**
   * 清理分析资源
   */
  private cleanupAnalysis(): void {
    logger.debug(`[${this.name}] 清理分析资源`)
    this.reset()
  }

  /**
   * 收集用户数据
   */
  private async collectAllData(): Promise<void> {
    const userInfo = this.collectUserInfo(this.currentConfig!)
    const scripts = this.collectScriptData(this.currentConfig!)
    let comments: UserAnalyticsCommentData[] = []

    const selector = this.currentConfig!.discussion.url
    this.discussionUrl = $(selector).attr('href') || ''
    if (!this.discussionUrl) {
      logger.warn(`[${this.name}] 讨论页面链接为空，无法提取评论`, selector)
    }
    else {
      comments = await this.collectCommentData(this.currentConfig!)
    }

    this.userData = {
      userInfo,
      scripts,
      comments,
    }

    logger.info(`[${this.name}] 数据收集完成`, this.userData)
  }

  /**
   * 收集用户信息
   */
  private collectUserInfo(config: UserAnalyticsConfig): UserAnalyticsUserData {
    return {
      name: $(config.userInfo.name).text().trim(),
      profileUrl: '',
      joinDate: '',
    }
  }

  /**
   * 收集脚本数据
   */
  private collectScriptData(config: UserAnalyticsConfig): UserAnalyticsScriptData[] {
    const scripts: UserAnalyticsScriptData[] = []
    const $scriptElements = $(config.selector)

    $scriptElements.each((index, element) => {
      try {
        const $element = $(element)
        const $script = $(element).find(config.script)
        const $stats = $element.find(config.stats.selector)
        const $ratings = $stats.find(config.stats.ratings.selector)
        const goodRatingCount = Number($ratings.find(config.stats.ratings.goodRatingCount).text().trim())
        const okRatingCount = Number($ratings.find(config.stats.ratings.okRatingCount).text().trim())
        const badRatingCount = Number($ratings.find(config.stats.ratings.badRatingCount).text().trim())
        const totalRatings = goodRatingCount + okRatingCount + badRatingCount

        const scriptData: UserAnalyticsScriptData = {
          id: $element.attr('data-script-id') || `script-${index}`,
          name: $script.text().trim(),
          url: $script.attr('href') || '',
          createdDate: ToolKit.time.parseTimestamp($stats.find(config.stats.createdDate).attr('datetime') || ''),
          updatedDate: ToolKit.time.parseTimestamp($stats.find(config.stats.updatedDate).attr('datetime') || ''),
          dailyInstalls: Number($stats.find(config.stats.dailyInstalls).text().replace(/,/g, '').trim()),
          totalInstalls: Number($stats.find(config.stats.totalInstalls).text().replace(/,/g, '').trim()),
          totalRatings,
          ratings: {
            good: goodRatingCount,
            ok: okRatingCount,
            bad: badRatingCount,
          },
        }
        scripts.push(scriptData)
      }
      catch (error) {
        logger.warn(`[${this.name}] 提取脚本数据失败`, { index, error })
      }
    })

    logger.info(`[${this.name}] 收集到 ${scripts.length} 个脚本`)
    return scripts
  }

  /**
   * 收集评论数据
   */
  private async collectCommentData(config: UserAnalyticsConfig): Promise<UserAnalyticsCommentData[]> {
    let comments: UserAnalyticsCommentData[] = []

    try {
      if (this.discussionUrl) {
        // 检查是否已取消
        if (this.progressManager.isCancelled())
          return comments

        this.progressManager.update({
          stage: ProgressStage.COLLECTING,
          message: '正在获取用户留言...',
          percentage: this.COMMENT_START_PROGRESS + 1,
          details: '准备访问讨论页面',
        })

        // 从讨论页面提取评论
        const result = await this.fetchCommentsFromDiscussion(this.discussionUrl, config)

        // 检查是否已取消
        if (this.progressManager.isCancelled())
          return comments

        // 处理 IframeOperationResult 结果
        if (result.success && result.data) {
          comments = result.data

          // 记录统计信息
          if (result.metadata) {
            const { totalPages, totalComments, hasMore } = result.metadata
            this.actualCommentPages = totalPages

            logger.info(`[${this.name}] 评论获取统计`, {
              totalComments: comments.length,
              pagesFetched: totalPages,
              hasMore,
            })

            // 检查是否已取消
            if (!this.progressManager.isCancelled()) {
              // 更新进度：评论获取完成
              this.progressManager.update({
                stage: ProgressStage.COLLECTING,
                message: `已获取 ${totalComments} 条留言`,
                percentage: this.COMMENT_COLLECTED_PROGRESS,
                details: `从 ${totalPages} 个页面中提取${hasMore ? '（还有更多页面）' : ''}`,
              })
            }
          }
        }
        else {
          logger.warn(`[${this.name}] 获取评论数据失败`, result.error)

          // 检查是否已取消
          if (!this.progressManager.isCancelled()) {
            this.progressManager.update({
              stage: ProgressStage.COLLECTING,
              message: '获取留言失败',
              percentage: this.COMMENT_COLLECTED_PROGRESS,
              details: result.error?.message || '未知错误',
            })
          }
        }
      }
    }
    catch (error) {
      // 如果是取消操作，不记录为错误
      if (this.progressManager.isCancelled())
        return comments

      logger.error(`[${this.name}] 收集评论数据失败`, error)

      this.progressManager.update({
        stage: ProgressStage.ERROR,
        message: '收集留言数据失败',
        percentage: this.COMMENT_COLLECTED_PROGRESS,
        details: error instanceof Error ? error.message : '未知错误',
      })
    }

    logger.info(`[${this.name}] 收集到 ${comments.length} 条评论`)
    return comments
  }

  private fetchCommentsFromDiscussion(discussionUrl: string, config: UserAnalyticsConfig): Promise<DocumentFetchResult<UserAnalyticsCommentData[]>> {
    // 如果不启用分页或只获取第一页
    if (!this.enablePagination || this.maxCommentPages === 1) {
      return this.fetchSinglePageComments(discussionUrl, config, 1)
    }

    // 多页获取
    return this.fetchMultiPageComments(discussionUrl, config)
  }

  /**
   * 获取单页评论数据
   */
  private async fetchSinglePageComments(
    url: string,
    config: UserAnalyticsConfig,
    page: number = 1,
  ): Promise<DocumentFetchResult<UserAnalyticsCommentData[]>> {
    const startTime = Date.now()
    const pageUrl = ToolKit.browser.url.buildUrlParam(url, 'page', page, { defaultValue: 1 })
    const fullUrl = ToolKit.browser.url.getFullUrl(url)
    const userId = ToolKit.browser.url.getUrlParam(fullUrl, 'user') || ''

    try {
      const result = await this.documentOperator.fetchDocument({
        url: pageUrl,
      })

      const doc = result.data || document
      const comments = await this.extractCommentInfo($(doc), config, userId, page)

      return {
        ...result,
        data: comments,
      }
    }
    catch (error) {
      logger.error(`[${this.name}] 获取第 ${page} 页评论失败`, error)

      return {
        success: false,
        error: error instanceof Error ? error : new Error(String(error)),
        url: pageUrl,
        encoding: '',
        methodUsed: 'GET',
        duration: Date.now() - startTime,
        retryCount: 0,
      }
    }
  }

  /**
   * 获取多页评论数据
   */
  private async fetchMultiPageComments(
    baseUrl: string,
    config: UserAnalyticsConfig,
  ): Promise<DocumentFetchResult<UserAnalyticsCommentData[]>> {
    const paginationConfig = await this.getPaginationConfig()
    const { maxPages, startPage = 1, loadAll = false } = paginationConfig
    const allComments: UserAnalyticsCommentData[] = []
    let hasMorePages = true
    let currentPage = startPage
    const startTime = Date.now()
    let encoding = ''

    try {
      logger.info(`[${this.name}] 开始获取多页评论`, {
        maxPages,
        loadAll,
        totalExpectedPages: loadAll ? '全部' : maxPages,
      })

      // 顺序获取每一页评论
      for (let page = startPage; page <= maxPages && hasMorePages; page++) {
        // 检查是否已取消
        if (this.progressManager.isCancelled()) {
          logger.info(`[${this.name}] 用户取消，停止获取第 ${page} 页评论`)
          break
        }

        // 更新分页进度
        this.progressManager.update({
          stage: ProgressStage.COLLECTING,
          message: `正在获取第 ${page} 页留言...`,
          percentage: this.COMMENT_START_PROGRESS + Math.floor((page - startPage) / (maxPages - startPage + 1) * (this.COMMENT_COLLECTED_PROGRESS - this.COMMENT_START_PROGRESS)),
          details: `已获取 ${allComments.length} 条留言，当前页: ${page}/${maxPages}`,
        })

        logger.debug(`[${this.name}] 正在获取第 ${page} 页评论...`)

        const result = await this.fetchSinglePageComments(baseUrl, config, page)

        if (result.success && result.data) {
          if (result.data.length > 0) {
            allComments.push(...result.data)
            logger.debug(`[${this.name}] 第 ${page} 页获取到 ${result.data.length} 条评论`)
          }
          else {
            hasMorePages = false
            logger.notice(`[${this.name}] ${SYMBOLS.STATUS.WARNING} 第 ${page} 页无评论，停止获取`)
          }

          encoding = result.encoding || ''
        }
        else {
          logger.warn(`[${this.name}] 第 ${page} 页获取失败`, result.error)
          break
        }

        // 添加延迟，避免请求过快
        if (page < maxPages && hasMorePages)
          await ToolKit.async.delay(500)

        currentPage = page
      }

      const duration = Date.now() - startTime

      // 如果是取消操作，返回部分结果
      if (this.progressManager.isCancelled()) {
        logger.info(`[${this.name}] 用户取消操作，返回已获取的 ${allComments.length} 条评论`)

        return {
          success: true,
          url: baseUrl,
          encoding,
          methodUsed: 'GET',
          data: allComments,
          retryCount: 0,
          duration,
          metadata: {
            totalPages: currentPage,
            totalComments: allComments.length,
            hasMore: hasMorePages,
            cancelled: true, // 标记为已取消
          },
        }
      }

      logger.info(`[${this.name}] 多页数据获取完成，共从 ${currentPage} 页中获取 ${allComments.length} 条评论`)

      return {
        success: true,
        data: allComments,
        url: baseUrl,
        encoding,
        methodUsed: 'GET',
        retryCount: 0,
        duration,
        metadata: {
          totalPages: currentPage,
          totalComments: allComments.length,
          hasMore: hasMorePages,
        },
      }
    }
    catch (error) {
      const duration = Date.now() - startTime

      // 如果是取消操作，不记录为错误
      if (this.progressManager.isCancelled()) {
        return {
          success: true,
          data: allComments,
          url: baseUrl,
          encoding,
          methodUsed: 'GET',
          retryCount: 0,
          duration,
          metadata: {
            totalPages: currentPage,
            totalComments: allComments.length,
            hasMore: false,
            cancelled: true,
          },
        }
      }

      logger.error(`[${this.name}] 多页评论获取失败`, error)

      return {
        success: false,
        error: error instanceof Error ? error : new Error('多页评论获取失败'),
        data: allComments, // 返回已获取的数据
        url: baseUrl,
        encoding,
        methodUsed: 'GET',
        retryCount: 0,
        duration,
        metadata: {
          totalPages: currentPage,
          totalComments: allComments.length,
          hasMore: false,
        },
      }
    }
  }

  /**
   * 获取分页配置（先获取第一页以确定总页数）
   */
  private async getPaginationConfig(): Promise<UserAnalyticsMultiPageOptions> {
    // 如果已经有页面最大页数，直接使用
    if (this.pageMaxCommentPages > 0)
      return this.buildPaginationConfig()

    // 如果没有页面最大页数，先获取第一页来确定总页数
    try {
      logger.debug(`[${this.name}] 正在获取页面总数...`)

      // 获取第一页数据来确定总页数
      const firstPageResult = await this.fetchSinglePageComments(this.discussionUrl, this.currentConfig!, 1)

      if (firstPageResult.success && this.pageMaxCommentPages > 0) {
        logger.important(`[${this.name}] 页面总数获取成功: ${this.pageMaxCommentPages} 页`)
      }
      else {
        logger.warn(`[${this.name}] 无法获取页面总数，使用默认值: ${this.maxCommentPages} 页`)
        this.pageMaxCommentPages = this.maxCommentPages
      }
    }
    catch (error) {
      logger.warn(`[${this.name}] 获取页面总数失败，使用默认值`, error)
      this.pageMaxCommentPages = this.maxCommentPages
    }

    return this.buildPaginationConfig()
  }

  /**
   * 获取分页配置
   */
  private buildPaginationConfig(): UserAnalyticsMultiPageOptions {
    const actualMaxPages = this.getActualMaxPages()

    logger.debug(`[${this.name}] 留言分页配置`, {
      customMaxPages: this.customMaxCommentPages,
      pageMaxPages: this.pageMaxCommentPages,
      defaultMaxPages: this.maxCommentPages,
      actualMaxPages,
      loadAll: this.customMaxCommentPages === 0,
    })

    return {
      maxPages: actualMaxPages,
      startPage: 1,
      loadAll: this.customMaxCommentPages === 0,
    }
  }

  /**
   * 获取实际最大页数
   */
  private getActualMaxPages(): number {
    // 如果用户自定义页数为0，则加载全部页面
    if (this.customMaxCommentPages === 0) {
      // 使用页面实际最大页数，但不能为 0
      return Math.max(this.pageMaxCommentPages || 1, 1)
    }

    // 如果用户设置了自定义页数，使用较小的值（自定义页数或实际最大页数）
    return Math.min(
      this.customMaxCommentPages,
      this.pageMaxCommentPages || this.maxCommentPages,
    )
  }

  /**
   * 从讨论页面提取评论数据
   */
  private extractCommentInfo(
    $iframeDoc: JQuery<Document>,
    config: UserAnalyticsConfig,
    userId: string,
    pageNum: number,
  ): Promise<UserAnalyticsCommentData[]> {
    return new Promise((resolve, _reject) => {
      const comments: UserAnalyticsCommentData[] = []
      const $pageNumItems = $iframeDoc.find(GREASY_FORK_PAGINATION_CONFIG.selector.item)
      const maxPageNum = ToolKit.ui.element.extractMaxNumberFromElements($pageNumItems)

      // 更新页面最大页数
      if (maxPageNum > 0 && !this.pageMaxCommentPages) {
        this.pageMaxCommentPages = maxPageNum
        logger.debug(`[${this.name}] 更新页面最大页数为: ${this.pageMaxCommentPages}`)
      }

      // 更新实际获取页数
      this.actualCommentPages = pageNum || 1

      if (pageNum > maxPageNum) {
        logger.debug(`[${this.name}] 第 ${pageNum} 页超出最大页数 ${maxPageNum}`)
        resolve(comments)
        return
      }

      $iframeDoc.find(config.discussion.selector).each((index, element) => {
        try {
          const $element = $(element)
          const $commentUrl = $element.find(config.discussion.commentUrl)
          const $scriptName = $element.find(config.discussion.scriptName)
          const $rating = $element.find(config.discussion.rating)

          const $user = $element.find(config.discussion.user.selector)
          const { role, timestamp } = this.getUserInfo($user, config, userId)

          const commentUrl = $commentUrl.attr('href') || ''

          const commentData: UserAnalyticsCommentData = {
            id: commentUrl.match(/discussions\/(\d+)$/)?.[1] || `comment-${pageNum}-${index}`,
            url: commentUrl,
            scriptName: $scriptName.text().trim(),
            scriptUrl: $scriptName.attr('href') || '',
            role,
            rating: $rating.hasClass('rating-icon-good')
              ? 'good'
              : $rating.hasClass('rating-icon-ok')
                ? 'ok'
                : $rating.hasClass('rating-icon-bad')
                  ? 'bad'
                  : 'none',
            content: ToolKit.string.truncate($element.find(config.discussion.content).text().trim(), 100),
            timestamp: ToolKit.time.parseTimestamp(timestamp),
            pageNum: maxPageNum,
            positionInPage: index + 1, // 在页面中的位置
          }

          if (commentData.role !== UserAnalyticsCommentRole.Author)
            comments.push(commentData)
        }
        catch (error) {
          logger.warn(`[${this.name}] 提取评论数据失败`, { pageNum, index, error })
        }
      })

      logger.debug(`[${this.name}] 第 ${pageNum} 页提取到 ${comments.length} 条评论`)
      resolve(comments)
    })
  }

  /**
   * 从元素中提取用户信息
   */
  getUserInfo($elements: JQuery<Element>, config: UserAnalyticsConfig, userId: string): { role: UserAnalyticsCommentRole, timestamp: string } {
    let role: UserAnalyticsCommentRole = UserAnalyticsCommentRole.Author
    let timestamp = ''

    $elements.each((index, element) => {
      const $element = $(element)

      const currentUserUrl = $element.find(config.discussion.user.url).attr('href') || ''
      const currentTimestamp = $element.find(config.discussion.user.createdDate).attr('datetime') || ''

      if (currentUserUrl.includes(`/users/${userId}-`)) {
        timestamp = currentTimestamp

        // 非第一个元素为回答者
        if (index !== 0) {
          role = UserAnalyticsCommentRole.Answerer
        }
        else {
          role = UserAnalyticsCommentRole.OriginalPoster
        }
      }
    })

    return {
      role,
      timestamp,
    }
  }

  /**
   * 分析数据
   */
  analyzeData(): void {
    if (!this.userData) {
      logger.warn(`[${this.name}] 未收集到用户数据，无法分析`)
      return
    }

    const { scripts, comments } = this.userData
    // 楼主的评论
    const originalPosterComment = comments
      .filter(item => item.role === UserAnalyticsCommentRole.OriginalPoster)
    // 回答者的评论
    const answererComment = comments
      .filter(item => item.role === UserAnalyticsCommentRole.Answerer)

    this.analyticsData = {
      // 脚本统计
      totalScripts: scripts.length,
      scriptTotalInstallRanges: this.calculateTotalInstallRanges(scripts),
      scriptDailyInstallRanges: this.calculateDailyInstallRanges(scripts),
      allTotalInstalls: ToolKit.string.getExtremeFieldValue(scripts, 'totalInstalls', 'sum') as number,
      allDailyInstalls: ToolKit.string.getExtremeFieldValue(scripts, 'dailyInstalls', 'sum') as number,
      maxTotalInstalls: ToolKit.string.getExtremeFieldValue(scripts, 'totalInstalls', 'max') as number,
      maxDailyInstalls: ToolKit.string.getExtremeFieldValue(scripts, 'dailyInstalls', 'max') as number,
      topDailyInstalls: this.getTopScripts(scripts, 'dailyInstalls', 3),
      topTotalInstalls: this.getTopScripts(scripts, 'totalInstalls', 3),
      zeroInstallScripts: scripts.filter(item => item.totalInstalls === 0),
      zeroBadRatingScripts: scripts.filter(item => item.ratings.bad === 0 && (item.ratings.good + item.ratings.ok + item.ratings.bad > 0)),

      // 创建时间统计
      firstCreation: ToolKit.string.getExtremeFieldValue(
        scripts,
        'createdDate',
        'min',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsScriptData,
      lastCreation: ToolKit.string.getExtremeFieldValue(
        scripts,
        'createdDate',
        'max',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsScriptData,
      firstUpdate: ToolKit.string.getExtremeFieldValue(
        scripts,
        'updatedDate',
        'min',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsScriptData,
      lastUpdate: ToolKit.string.getExtremeFieldValue(
        scripts,
        'updatedDate',
        'max',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsScriptData,
      creationTimeDistribution: this.calculateCreationTimeDistribution(scripts),

      // 更新时间统计
      updateTimeDistribution: this.calculateUpdateTimeDistribution(scripts),
      updateHourDistribution: ToolKit.time.extractHourDistribution(scripts.map(item => item.updatedDate)),

      // 评价统计
      maxScriptRating: ToolKit.string.getExtremeFieldValue(scripts, 'totalRatings', 'max') as number,
      scriptRatingDistribution: this.calculateRatingDistribution(scripts),
      topRatedScripts: this.getTopRatedScripts(scripts, 3),
      topBadRatedScripts: this.getTopBadRatedScripts(scripts, 3),
      mostRatedScripts: this.getMostRatedScripts(scripts, 3),
      unratedScripts: this.getUnratedScripts(scripts),

      // 留言统计
      commentPageNum: Object.values(comments).find(item => item.pageNum)?.pageNum || 1,
      totalComments: comments.length,
      totalAnswererComments: answererComment.length,
      totalCommentScript: new Set(comments.map(item => item.scriptUrl)).size,
      totalPostScript: new Set(originalPosterComment.map(item => item.scriptUrl)).size,
      commentScriptGoodRating: new Set(originalPosterComment.filter(item => item.rating === 'good').map(item => item.scriptUrl)).size,
      commentScriptBadRating: new Set(originalPosterComment.filter(item => item.rating === 'bad').map(item => item.scriptUrl)).size,
      commentScriptDistribution: this.calculateCommentScriptDistribution(originalPosterComment),
      commentRatingDistribution: this.calculateCommentRatingDistribution(originalPosterComment),
      firstComment: ToolKit.string.getExtremeFieldValue(
        comments,
        'timestamp',
        'min',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsCommentData,
      lastComment: ToolKit.string.getExtremeFieldValue(
        comments,
        'timestamp',
        'max',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsCommentData,
      firstOriComment: ToolKit.string.getExtremeFieldValue(
        originalPosterComment,
        'timestamp',
        'min',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsCommentData,
      firstAnswererComment: ToolKit.string.getExtremeFieldValue(
        answererComment,
        'timestamp',
        'min',
        'date',
        { returnType: 'item' },
      ) as UserAnalyticsCommentData,
      commentTimeDistribution: this.calculateCommentTimeDistribution(comments),

      // 用户活跃度
      commentFrequency: this.calculateCommentFrequency(comments),
      updateFrequency: this.calculateUpdateFrequency(scripts),
    }

    this.analyticsData.daysSinceLastComment = ToolKit.time.calculateDurationDays(
      this.analyticsData.lastComment.timestamp,
      Date.now(),
    )
    this.analyticsData.daysSinceLastScriptUpdate = ToolKit.time.calculateDurationDays(
      ToolKit.time.getLatestTime([
        this.analyticsData.lastCreation.updatedDate,
        this.analyticsData.lastUpdate.updatedDate,
      ]) || 0,
      Date.now(),
    )

    this.analyticsData.recentActivities = this.collectRecentActivities(this.userData)

    logger.info(`[${this.name}] 数据分析完成`, this.analyticsData)
  }

  /**
   * 计算安装量分布
   */
  private calculateTotalInstallRanges(scripts: UserAnalyticsScriptData[]): UserAnalyticsScriptTotalInstallRanges {
    const ranges: UserAnalyticsScriptTotalInstallRanges = {
      '0': 0,
      '0-1k': 0,
      '1k-1w': 0,
      '1w-5w': 0,
      '5w-10w': 0,
      '10w-100w': 0,
      '100w-500w': 0,
      '500w-1m': 0,
      '1m+': 0,
    }

    scripts.forEach((script) => {
      const installs = script.totalInstalls
      if (installs === 0)
        ranges['0']++
      else if (installs <= 1000)
        ranges['0-1k']++
      else if (installs <= 10000)
        ranges['1k-1w']++
      else if (installs <= 50000)
        ranges['1w-5w']++
      else if (installs <= 100000)
        ranges['5w-10w']++
      else if (installs <= 1000000)
        ranges['10w-100w']++
      else if (installs <= 5000000)
        ranges['100w-500w']++
      else if (installs <= 10000000)
        ranges['500w-1m']++
      else ranges['1m+']++
    })

    return ranges
  }

  /**
   * 计算每日安装量分布
   */
  private calculateDailyInstallRanges(scripts: UserAnalyticsScriptData[]): UserAnalyticsScriptDailyInstallRanges {
    const ranges: UserAnalyticsScriptDailyInstallRanges = {
      '0': 0,
      '0-50': 0,
      '50-80': 0,
      '80-100': 0,
      '100-150': 0,
      '150-200': 0,
      '200+': 0,
    }
    scripts.forEach((script) => {
      const installs = script.dailyInstalls
      if (installs === 0)
        ranges['0']++
      else if (installs <= 50)
        ranges['0-50']++
      else if (installs <= 80)
        ranges['50-80']++
      else if (installs <= 100)
        ranges['80-100']++
      else if (installs <= 150)
        ranges['100-150']++
      else if (installs <= 200)
        ranges['150-200']++
      else ranges['200+']++
    })

    return ranges
  }

  /**
   * 获取排名前 N 的脚本
   */
  private getTopScripts(scripts: UserAnalyticsScriptData[], field: keyof UserAnalyticsScriptData, count: number): UserAnalyticsScriptData[] {
    return [...scripts]
      .sort((a, b) => {
        const aValue = a[field] as number
        const bValue = b[field] as number

        // 主要排序：按指定字段降序
        if (aValue !== bValue) {
          return bValue - aValue
        }

        // 次要排序：相同数据量时按更新时间降序（最新的在前）
        const aUpdateTime = a.updatedDate
        const bUpdateTime = b.updatedDate
        return bUpdateTime - aUpdateTime
      })
      .slice(0, count)
      .filter(script => (script[field] as number) > 0)
  }

  /**
   * 计算创建时间分布
   */
  private calculateCreationTimeDistribution(scripts: UserAnalyticsScriptData[]): UserAnalyticsCreationTimeDistribution {
    const distribution: UserAnalyticsCreationTimeDistribution = {
      byYear: {},
    }

    scripts.forEach((script) => {
      if (!script.createdDate)
        return

      const year = ToolKit.time.formatYear(script.createdDate)

      distribution.byYear[year] = (distribution.byYear[year] || 0) + 1
    })

    return distribution
  }

  /**
   * 计算更新时间分布（按星期）
   */
  private calculateUpdateTimeDistribution(scripts: UserAnalyticsScriptData[]): Record<string, number> {
    const distribution: Record<string, number> = WEEKDAYS_CHINESE.reduce((acc, day) => ({ ...acc, [day]: 0 }), {})

    scripts.forEach((script) => {
      if (script.updatedDate) {
        const date = new Date(script.updatedDate)
        const weekday = WEEKDAYS_CHINESE[(date.getDay() + 6) % 7]
        distribution[weekday] = (distribution[weekday] || 0) + 1
      }
    })

    return distribution
  }

  /**
   * 计算评价分布
   */
  private calculateRatingDistribution(scripts: UserAnalyticsScriptData[]): { good: number, ok: number, bad: number } {
    const distribution = { good: 0, ok: 0, bad: 0 }

    scripts.forEach((script) => {
      distribution.good += script.ratings.good
      distribution.ok += script.ratings.ok
      distribution.bad += script.ratings.bad
    })

    return distribution
  }

  /**
   * 获取好评最多的脚本
   */
  private getTopRatedScripts(scripts: UserAnalyticsScriptData[], count: number): UserAnalyticsScriptData[] {
    return [...scripts]
      .sort((a, b) => b.ratings.good - a.ratings.good)
      .slice(0, count)
      .filter(script => script.ratings.good > 0)
  }

  /**
   * 获取差评最多的脚本
   */
  private getTopBadRatedScripts(scripts: UserAnalyticsScriptData[], count: number): UserAnalyticsScriptData[] {
    return [...scripts]
      .sort((a, b) => b.ratings.bad - a.ratings.bad)
      .slice(0, count)
      .filter(script => script.ratings.bad > 0)
  }

  /**
   * 获取评价最多的脚本
   */
  private getMostRatedScripts(scripts: UserAnalyticsScriptData[], count: number): UserAnalyticsScriptData[] {
    return [...scripts]
      .sort((a, b) => {
        const aTotal = a.ratings.good + a.ratings.ok + a.ratings.bad
        const bTotal = b.ratings.good + b.ratings.ok + b.ratings.bad
        return bTotal - aTotal
      })
      .slice(0, count)
      .filter(script => (script.ratings.good + script.ratings.ok + script.ratings.bad) > 0)
  }

  /**
   * 获取无评价脚本
   */
  private getUnratedScripts(scripts: UserAnalyticsScriptData[]): UserAnalyticsScriptData[] {
    return scripts.filter(script =>
      script.ratings.good === 0
      && script.ratings.ok === 0
      && script.ratings.bad === 0,
    )
  }

  /**
   * 计算评论按脚本分布
   */
  private calculateCommentScriptDistribution(comments: UserAnalyticsCommentData[]): UserAnalyticsCommentScriptDistribution {
    const distribution: UserAnalyticsCommentScriptDistribution = {}

    comments.forEach((comment) => {
      const scriptName = comment.scriptName
      const historyTimestamp = distribution[scriptName]?.timestamp || 0
      const currentTimestamp = comment.timestamp

      distribution[scriptName] = {
        count: (distribution[scriptName]?.count || 0) + 1,
        timestamp: currentTimestamp > historyTimestamp ? currentTimestamp : historyTimestamp,
      }
    })

    return distribution
  }

  /**
   * 计算评论按评价分布
   */
  private calculateCommentRatingDistribution(comments: UserAnalyticsCommentData[]): { good: number, ok: number, bad: number, none: number } {
    const distribution = { good: 0, ok: 0, bad: 0, none: 0 }

    comments.forEach((comment) => {
      distribution[comment.rating]++
    })

    return distribution
  }

  /**
   * 计算评论时间分布
   */
  private calculateCommentTimeDistribution(comments: UserAnalyticsCommentData[]): { byWeekday: number[], byHour: number[] } {
    const byWeekday = Array.from<number>({ length: 7 }).fill(0)
    const byHour = Array.from<number>({ length: 24 }).fill(0)

    comments.forEach((comment) => {
      if (comment.timestamp) {
        const date = new Date(comment.timestamp)
        byWeekday[date.getDay()]++
        byHour[date.getHours()]++
      }
    })

    return { byWeekday, byHour }
  }

  /**
   * 计算评论频率（条/周）
   */
  private calculateCommentFrequency(comments: UserAnalyticsCommentData[]): number {
    const duration = this.calculateCommentDuration(comments)
    const frequency = duration > 0 ? comments.length / duration : comments.length
    return Number.parseFloat(frequency.toFixed(2))
  }

  /**
   * 计算评论时间跨度（周）
   */
  private calculateCommentDuration(comments: UserAnalyticsCommentData[]): number {
    const dates = comments
      .map(comment => comment.timestamp)
      .filter(Boolean)
      .map(date => new Date(date).getTime())

    if (dates.length < 2)
      return 0

    const minDate = Math.min(...dates)
    const maxDate = Math.max(...dates)
    return Math.ceil((maxDate - minDate) / (1000 * 60 * 60 * 24 * 7))
  }

  /**
   * 计算更新频率（次/周）
   */
  private calculateUpdateFrequency(scripts: UserAnalyticsScriptData[]): number {
    const duration = this.calculateUpdateDuration(scripts)
    const frequency = duration > 0 ? scripts.length / duration : scripts.length
    return Number.parseFloat(frequency.toFixed(2))
  }

  /**
   * 计算更新时间跨度（周）
   */
  private calculateUpdateDuration(scripts: UserAnalyticsScriptData[]): number {
    const dates = scripts
      .map(script => script.updatedDate)
      .filter(Boolean)
      .map(date => new Date(date).getTime())

    if (dates.length < 2)
      return 0

    const minDate = Math.min(...dates)
    const maxDate = Math.max(...dates)
    return Math.ceil((maxDate - minDate) / (1000 * 60 * 60 * 24 * 7))
  }

  /**
   * 收集最近活动
   */
  private collectRecentActivities(userData: UserAnalyticsCollectedData): UserAnalyticsActivity[] {
    const activities: UserAnalyticsActivity[] = []
    const oneWeekAgo = Date.now() - TIME_UNITS.COMMON.INTERVALS.ONE_WEEK

    // 收集脚本创建活动
    userData.scripts.forEach((script) => {
      if (script.createdDate && new Date(script.createdDate).getTime() >= oneWeekAgo) {
        activities.push({
          type: 'script-created',
          timestamp: new Date(script.createdDate).getTime(),
          scriptName: script.name,
          scriptUrl: script.url,
        })
      }
    })

    // 收集脚本更新活动
    userData.scripts.forEach((script) => {
      if (script.updatedDate && new Date(script.updatedDate).getTime() >= oneWeekAgo) {
        activities.push({
          type: 'script-updated',
          timestamp: new Date(script.updatedDate).getTime(),
          scriptName: script.name,
          scriptUrl: script.url,
        })
      }
    })

    // 收集评论活动
    userData.comments.forEach((comment) => {
      if (comment.timestamp && new Date(comment.timestamp).getTime() >= oneWeekAgo) {
        activities.push({
          type: comment.role === UserAnalyticsCommentRole.Answerer ? 'reply-created' : 'post-created',
          timestamp: new Date(comment.timestamp).getTime(),
          scriptName: comment.scriptName,
          scriptUrl: comment.scriptUrl,
          commentUrl: comment.url,
          content: comment.content,
          rating: comment.rating,
        })
      }
    })

    // 按时间降序排序
    return activities.sort((a, b) => b.timestamp - a.timestamp)
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.setupAnalytics()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return `
#${this.BUTTON_ID} {
  position: absolute;
  top: 6px;
  right: 76px;
  padding-right: 30px !important;
  border: none;
  background: none;
  color: var(${this.themeVarService.link.default.text});
  
  &:hover {
    color: var(${this.themeVarService.link.default.textHover});
  }
  
  &.loading {
    pointer-events: none !important;
    
    &::after {
      ${this.stylesService.inlinePseudo.iconMask({
        backgroundImageId: ICON_IDS.action.refresh,
        color: `var(${this.themeVarService.icon.hover})`,
      })}
      position: absolute !important;
      right: 5px !important;
      top: 50% !important;
      animation: loadingRotate 1s linear infinite !important;
    }
  }
}

.${this.uiService.DASHBOARD_ID} {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 90%;
  max-width: 1200px;
  height: 85vh;
  background: var(${this.themeVarService.default.background.list});
  color: var(${this.themeVarService.default.text.secondary});
  border-radius: 12px;
  box-shadow: 
    0 20px 40px rgba(0, 0, 0, 0.1),
    0 0 0 100vmax rgba(0, 0, 0, 0.5); /* 添加遮罩效果 */
  z-index: 10000;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  
  a {
    ${this.stylesService.link.default()}
  }
  
  .dashboard-header {
    padding: 20px;
    background: var(--${PROJECT_PREFIX}-theme-toolbar-bg) !important;
    border-bottom: 1px solid var(${this.themeVarService.default.border.colorNeutral});
    display: flex;
    justify-content: space-between;
    align-items: center;
    
    h3 {
      margin: 0;
      font-size: 18px;
      font-weight: 600;
      color: var(${this.themeVarService.default.text.primary});
      
      small {
        font-size: 13px;
        font-weight: 400;
        color: var(${this.themeVarService.default.text.neutral});
      }
    }
    
    .dashboard-controls {
      display: flex;
      gap: 8px;
      
      ${BUTTON_TEMPLATE_STYLES.close}
    }
  }
  
  .dashboard-content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    
    .summary-cards {
      display: grid;
      grid-template-columns: repeat(4, minmax(200px, 1fr));
      gap: 16px;
      margin-bottom: 30px;
      
      .summary-card {
        background: transparent;
        border: 1px solid var(${this.themeVarService.default.border.colorNeutral});
        border-radius: 8px;
        padding: 16px;
        text-align: center;
        
        &.overview-card {
          grid-column: 1 / -1;
          text-align: left;
          border: none;
          padding: 0;
          
          .user-overview {
            display: flex;
            align-items: center;
            gap: 12px;
            
            .user-avatar img {
              width: 40px;
              height: 40px;
              border-radius: 50%;
            }
            
            .user-info {
              .user-name {
                font-size: 16px;
                font-weight: 600;
                color: var(${this.themeVarService.default.text.primary});
                margin-bottom: 4px;
              }
              .user-stats {
                display: flex;
                gap: 20px;
                flex-wrap: wrap;
                
                .stat {
                  font-size: 12px;
                  color: var(${this.themeVarService.default.text.secondary});
                  margin-right: 12px;
                }
              }
            }
          }
        }

        .card-icon {
          font-size: 24px;
          margin-bottom: 8px;
        }

        .card-content {
          .card-value {
            font-size: 24px;
            font-weight: 600;
            color: var(${this.themeVarService.default.text.primary});
            margin-bottom: 4px;
            
            small {
              font-size: 15px;
              font-weight: 400;
              color: var(${this.themeVarService.default.text.neutral});
            }
          }
          
          .card-label {
            font-size: 12px;
            color: var(${this.themeVarService.default.text.secondary});
          }
        }
      }
    }
    
    .content-container {
      display: flex;
      flex-direction: column;
      gap: 30px;
      
      h4 {
        margin: 0 0 16px 0;
        font-size: 16px;
        font-weight: 600;
        color: var(${this.themeVarService.default.text.primary});
        
        a {
          color: var(${this.themeVarService.default.text.secondary}) !important;
          
          &:hover {
             color: var(${this.themeVarService.link.default.text}) !important;
          }
        }
      }
      
      .latest-section {
        .recent-activities {
          margin-top: 15px;
          
          .activity-timeline {
            /* 空状态样式 */
            .no-recent-activities {
              text-align: center;
              padding: 10px;
              
              .empty-state {
                color: var(${this.themeVarService.default.text.neutral});
                
                p {
                  margin: 0;
                  font-size: 14px;
                }
              }
            }
            
            .activity-list {
              display: flex;
              flex-direction: column;
              gap: 12px;
              
              .activity-item {
                display: flex;
                align-items: flex-start;
                gap: 12px;
                padding: 10px;
                background: var(${this.themeVarService.default.background.left});
                border-radius: 6px;
                border-left: 3px solid var(${this.themeVarService.default.border.colorNeutral});
                transition: all 0.2s ease;
                
                .activity-icon {
                  font-size: 16px;
                  padding: 6px;
                  border-radius: 50%;
                  min-width: 32px;
                  height: 32px;
                  display: flex;
                  align-items: center;
                  justify-content: center;
                }
                
                .activity-content {
                  flex: 1;
                  min-width: 0;
                  
                  .activity-text {
                    font-size: 14px;
                    line-height: 1.4;
                    color: var(${this.themeVarService.default.text.primary});
                    margin-bottom: 4px;
                  }
                  
                  .activity-time {
                    font-size: 12px;
                    color: var(${this.themeVarService.default.text.secondary});
                  }
                }
              }
            }
          }
        }
      }

      .script-section {
        .script-rankings {
          display: grid;
          grid-template-columns: repeat(3, minmax(300px, 1fr));
          gap: 20px;
          margin-top: 20px;
          padding: 20px;
          border-radius: 8px;
          border: 1px solid var(${this.themeVarService.default.border.colorNeutral});
          
          .ranking-group {
            background: var(${this.themeVarService.default.background.right});
            padding: 15px;
            border-radius: 6px;
            border-right: 1px solid var(${this.themeVarService.default.border.colorNeutral});
            
            h5 {
              margin: 0 0 12px 0;
              font-size: 14px;
              font-weight: 600;
              color: var(${this.themeVarService.default.text.primary});
              text-align: center;
            }
            
            h6 {
              margin: 0 0 8px 0;
              font-size: 13px;
              font-weight: 600;
              color: var(${this.themeVarService.default.text.secondary});
              display: flex;
              align-items: center;
              gap: 4px;
            }
            
            .ranking-category {
              margin-bottom: 15px;
              border-bottom: 1px solid var(${this.themeVarService.default.border.colorNeutral});
              
              &:last-child {
                margin-bottom: 0;
                border-bottom: none;
              }            
  
              .no-data {
                font-size: 12px;
                color: var(${this.themeVarService.default.text.neutral});
                padding: 10px 0;
                font-style: italic;
              }
            }
            
            .script-list {
              all: unset;
              list-style: none;
              margin: 0;
              padding: 0;
              
              .script-item {
                display: flex;
                align-items: center;
                gap: 8px;
                padding: 6px 0;
                cursor: pointer;
                transition: background-color 0.2s ease;
                border: none;
                
                .script-name {
                  flex: 1;
                  font-size: 13px;
                  color: var(${this.themeVarService.default.text.primary});
                  text-decoration: none;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  white-space: nowrap;
                }
                
                .script-value {
                  font-size: 12px;
                  font-weight: 600;
                  padding: 2px 6px;
                  border-radius: 4px;
                  min-width: 60px;
                  text-align: center;
                }
              }
              
              .more-item {
                font-size: 12px;
                color: var(${this.themeVarService.default.text.neutral});
                text-align: center;
                padding: 8px 0;
                cursor: default;
                border: none;
                
                &:hover {
                  background-color: transparent !important;
                }
              }
            }
          }
        }
      }
      
      .comment-section {
        .comment-status {
          margin: 15px 0;
          padding: 0;
          
          .comment-status-item {
            display: flex;
            align-items: flex-start;
            gap: 12px;
            padding: 16px;         
            
            .comment-status-content {
              flex: 1;
              
              .comment-status-title {
                font-size: 14px;
                font-weight: 600;
                color: var(${this.themeVarService.default.text.secondary});
                margin-bottom: 4px;
              }
              
              .comment-status-desc {
                font-size: 12px;
                color: var(${this.themeVarService.default.text.neutral});
                line-height: 1.4;
              }
            }
          }
        }
      }
      
      .charts-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
        gap: 20px;
        margin-top: 16px;
        
        .chart-item {
          height: 300px;
          background: transparent;
          border-radius: 8px;
          padding: 16px;
          
          &:empty {
            display: none;
            height: 0;
          }
        }
      }
    }
  }
}
`
  }
}
